opencv实现等值线 |
您所在的位置:网站首页 › opencv 分辨率 › opencv实现等值线 |
我有一个形象面具,有一些我从Canny那里得到的轮廓。 我可以计算一个边界矩形(具有固定的给定角度)。 现在我需要将这两个区域分离到该矩形的左侧和右侧。 我怎样才能做到这一点? 请注意,我想要处理矩形内的区域,而不是轮廓的像素。 编辑 这是我如何从掩码获取每个边界矩形:cv::Mat img_edges; // mask with contours // Apply clustering to the edge mask from here // http://stackoverflow.com/questions/33825249/opencv-euclidean-clustering-vs-findcontours?noredirect=1#comment55433731_33825249 // Find boundary rectangle for (auto &contour: contours) { // Iterate over every contour cluster cv::Mat Srot = cv::getRotationMatrix2D(cv::Point2f(float(img_edges.cols) / 2., float(img_edges.rows) / 2.), -ILLUMINATION_ANGLE_DEG, 1.0); cv::transform(contour, contour, Srot); float min_x, min_y, max_x, max_y; min_x = min_y = std::numeric_limits::max(); max_x = max_y = -std::numeric_limits::max(); // Simply find edges of aligned rectangle, then rotate back by inverse of Srot } 好吧,让我们假设我可以获得连接组件。 我该如何继续? 从评论到问题,我们同意这个程序应该适用于轴对齐的矩形。 这不会失去一般性,因为您可以将旋转的矩形旋转为轴对齐,应用此过程,然后再旋转点。 从具有一些边缘的示例图像开始,如: 你可以得到像这样的东西,其中蓝色是由边缘分隔的边界框中的左边部分,红色是右边部分: 这个算法可能不是最聪明的做法,但在实践中可以正常工作。 找到每条边的边界框后: 在给定的roi上创建一个矩阵tmp ,再加上左边的1列和右边的1。 这将使算法对特定情况具有鲁棒性。 移动新坐标系中的所有边界点,然后绘制到tmp 。 应用floodFill算法来查找左边的点。 种子是tmp左上角。 应用floodFill算法找到正确的点。 种子是tmp右上角。 检索两个区域中的点,转移到原始坐标系。 这里的评论代码,如果有什么不明确的话,请ping我:#include #include using namespace std; using namespace cv; void separateAreas(const Rect& roi, const vector& points, vector& left, vector& right) { left.clear(); right.clear(); // Temporary matrix // 0 : background pixels // 1 : boundary pixels // 2 : left pixels // 3 : right pixels Mat1b tmp(roi.height, roi.width + 2, uchar(0)); // Shift points to roi origin, i.e tmp(0,1) vector pts(points); for (int i = 0; i { pts[i] -= roi.tl(); // Draw boundary on tmp matrix tmp(pts[i] + Point(1,0)) = 1; } // Fill left area, seed top left point floodFill(tmp, Point(0, 0), Scalar(2)); // Fill right area, seed top right point floodFill(tmp, Point(tmp.cols-1, 0), Scalar(3)); // Find left and right points findNonZero(tmp.colRange(1, tmp.cols - 1) == 2, left); findNonZero(tmp.colRange(1, tmp.cols - 1) == 3, right); // Shift back for (int i = 0; i { left[i] += roi.tl(); } for (int i = 0; i { right[i] += roi.tl(); } } int main() { Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE); Mat3b res; cvtColor(img, res, COLOR_GRAY2BGR); vector> contours; findContours(img.clone(), contours, RETR_LIST, CV_CHAIN_APPROX_NONE); for (int i = 0; i { Rect roi = boundingRect(contours[i]); //rectangle(res, roi, Scalar(0,255,0)); vector left, right; separateAreas(roi, contours[i], left, right); // Draw areas on res for (int j = 0; j { res(left[j]) = Vec3b(255,0,0); // Blue for left } for (int j = 0; j { res(right[j]) = Vec3b(0, 0, 255); // Red for right } } imshow("Image", img); imshow("Result", res); waitKey(); return 0; } 链接地址: http://www.djcxy.com/p/89725.html |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |